package util

import (
	"fmt"
	"github.com/topfreegames/pitaya/constants"
	"github.com/topfreegames/pitaya/session"
	"reflect"
	"strconv"
	"time"
)

func Now() int64 {
	return time.Now().UnixNano() / 1e6
}

func NowMonth(now time.Time) int {
	v,err := strconv.ParseInt(now.Format("01"),10,32)
	if err != nil {
		return 0
	}

	return int(v)
}

/**
将时间转为毫秒数
 */
func GetTime(t time.Time) int64 {
	return t.UnixNano() / 1e6
}

/**
将毫秒数转为时间
 */
func GetData(t int64) time.Time {
	return time.Unix(t/1000,0)
}

/**
字符串转int64
 */
func CastLong(s string) int64 {
	r,err := strconv.ParseInt(s,10,64)
	if err != nil {
		return 0
	}

	return r
}

func GetRetRoute(route string) string {
	return fmt.Sprintf("%s_ret",route)
}

func GetAccountIdFromSession(s *session.Session) (int64,error) {
	if len(s.UID()) == 0 {
		return 0,constants.ErrNoUIDBind
	}

	accountId,err := strconv.ParseInt(s.UID(),10,64)
	if err != nil {
		return 0,err
	}

	return accountId,nil
}

func IntToByteArray(value int) []byte {
	arr := make([]byte,0)
	for i:= 0;i<4;i++ {
		arr = append(arr,byte(value >> (8*i))&0xFF)
	}

	return arr
}

func ByteArrayToInt32(bytes []byte,startIndex int) int32 {
	rs := 0
	for i:= 0;i<4 &&i + startIndex < len(bytes);i++{
		v := bytes[i+startIndex]
		rs |= int(v) << (8*i)
	}
	return int32(rs)
}

func ByteArrayToInt(bytes []byte,startIndex int) int {
	rs := 0
	for i:= 0;i< 4 &&i+startIndex < len(bytes);i++{
		v := bytes[i+startIndex]
		rs |= int(v) << (8*i)
	}
	return rs
}

func ByteArrayToInt64(bytes []byte,startIndex int) int64 {
	rs := int64(0)
	for i:= 0;i<8 &&i + startIndex < len(bytes);i++{
		v := bytes[i+startIndex]
		rs |= (int64)(int(v) << (8*i))
	}
	return rs
}

func ByteArrayToInt32Array(bytes []byte,srcIdx,srcLength int,desc []int32,descIdx int) {
	for i:=srcIdx;i<srcIdx + srcLength && i < len(bytes) && descIdx < len(desc); {
		value := 0
		for index := 0;index<4&&i<srcIdx + srcLength && i < len(bytes);index++{
			v := bytes[i]
			value |= int(v&0xFF) << (8*index)
			i ++
		}

		desc[descIdx] = int32(value)
		descIdx += 1
	}
}

func ByteArrayToIntArray(bytes []byte,srcIdx,srcLength int,desc []int,descIdx int) {
	for i:=srcIdx;i<srcIdx + srcLength && i < len(bytes) && descIdx < len(desc); {
		value := 0
		for index := 0;index<4&&i<srcIdx + srcLength && i < len(bytes);index++{
			v := bytes[i]
			value |= int(v&0xFF) << (8*index)
			i ++
		}

		desc[descIdx] = value
		descIdx += 1
	}
}


func IntArrayToByteArray(ints []int) []byte {
	if ints == nil || len(ints) == 0 {
		return nil
	}

	rs := []byte{}
	for _,v := range ints {
		for i:=0;i<4;i++{
			b := (v >> (8*i))&0xff
			if b == 0 {
				break
			}

			rs = append(rs,byte(b))
		}
	}

	return rs
}

func Int32ArrayToByteArray(ints []int32) []byte {
	if ints == nil || len(ints) == 0 {
		return nil
	}

	rs := []byte{}
	for _,v := range ints {
		for i:=0;i<4;i++{
			b := (v >> (8*i))&0xff
			if b == 0 {
				break
			}

			rs = append(rs,byte(b))
		}
	}

	return rs
}

/**
拷贝结构体
 */
func CopyStruct(src, dst interface{}) {
	sval := reflect.ValueOf(src).Elem()
	dval := reflect.ValueOf(dst).Elem()

	for i := 0; i < sval.NumField(); i++ {
		value := sval.Field(i)
		name := sval.Type().Field(i).Name

		dvalue := dval.FieldByName(name)
		if dvalue.IsValid() == false {
			continue
		}
		dvalue.Set(value) //这里默认共同成员的类型一样，否则这个地方可能导致 panic，需要简单修改一下。
	}
}